package com.hyl.crmclient.config.shiro;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.hyl.crmclient.service.RightService;
import com.hyl.jpademo.entity.Right;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description TODO
 * @Author hyl
 * @Date 2022/6/13 9:54
 **/
@Configuration
public class ShiroConfig {

	@Value("${spring.redis.database}")
	private Integer database;

	@Resource
	private RightService rightService;

	@Bean
	public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
		DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
		advisorAutoProxyCreator.setProxyTargetClass(true);
		return  advisorAutoProxyCreator;
	}

	@Bean
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
		AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
		authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
		return authorizationAttributeSourceAdvisor;
	}

	@Bean
	public ShiroDialect shiroDialect(){
		return new ShiroDialect();
	}


	public RedisManager redisManager(){
		RedisManager redisManager = new RedisManager();
		redisManager.setDatabase(database);
		return redisManager;
	}

	public RedisCacheManager redisCacheManager(){
		RedisCacheManager redisCacheManager = new RedisCacheManager();
		redisCacheManager.setRedisManager(redisManager());
		redisCacheManager.setPrincipalIdFieldName("usrName"); //认证中，身份==》字段
		redisCacheManager.setExpire(30*60);//秒
		return redisCacheManager;
	}

	public RedisSessionDAO redisSessionDAO(){
		RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
		redisSessionDAO.setRedisManager(redisManager());
		return redisSessionDAO;
	}

	public DefaultWebSessionManager sessionManager(){
		DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
		sessionManager.setSessionDAO(redisSessionDAO());
		return sessionManager;
	}

	@Bean
	public HashedCredentialsMatcher hashedCredentialsMatcher(){
		HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
		//算法
		hashedCredentialsMatcher.setHashAlgorithmName("md5");
		hashedCredentialsMatcher.setHashIterations(2);
		return hashedCredentialsMatcher;
	}

	@Bean
	public MyShiroRealm myShiroRealm(){
		MyShiroRealm realm = new MyShiroRealm();
		realm.setCachingEnabled(true);
		realm.setAuthorizationCachingEnabled(true);
		realm.setAuthorizationCacheName("authorizationCache");
		//添加密码匹配器
		realm.setCredentialsMatcher(hashedCredentialsMatcher());
		return realm;
	}

	@Bean
	public SecurityManager securityManager(){
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		securityManager.setRealm(myShiroRealm());
		//注入缓存管理器
		securityManager.setCacheManager(redisCacheManager());
		securityManager.setSessionManager(sessionManager());
		return securityManager;
	}

	@Bean
	public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
		ShiroFilterFactoryBean shiroFilterFactory = new ShiroFilterFactoryBean();
		shiroFilterFactory.setSecurityManager(securityManager);
		//url拦截
		shiroFilterFactory.setLoginUrl("/login"); //没有认证、授权前默认进入的页面
		shiroFilterFactory.setSuccessUrl("/index");
		shiroFilterFactory.setUnauthorizedUrl("/403");

		//添加控制权限
		Map<String,String> chainMap = new LinkedHashMap<String,String>();//必须有序LinkedHashMap
		//资源文件
		chainMap.put("/css/**","anon");
		chainMap.put("/fonts/**","anon");
		chainMap.put("/images/**","anon");
		chainMap.put("/js/**","anon");
		chainMap.put("/localcss/**","anon");
		chainMap.put("/localjs/**","anon");

		//默认请求：登入、注销
		chainMap.put("/login","anon");
		chainMap.put("/dologin","anon");
		chainMap.put("/logout","logout");

		//权限
		List<Right> list = rightService.findAll();
		for(Right tmp : list){
			if(tmp.getRightUrl()!=null && !tmp.getRightUrl().trim().equals("") ) {
				chainMap.put(tmp.getRightUrl(), "perms[" + tmp.getRightCode() + "]");
			}
		}
//		chainMap.put("/chance/list","perms[销售机会列表]");
//		chainMap.put("/chance/edit","perms[销售机会编辑]");
//		chainMap.put("/chance/add","perms[销售机会新增]");
//		chainMap.put("/chance/del","perms[销售机会删除]");
//		chainMap.put("/chance/view","perms[销售机会详情]");

		chainMap.put("/**","authc"); //必须放在最后

		shiroFilterFactory.setFilterChainDefinitionMap(chainMap);

		return shiroFilterFactory;
	}
}
